using Gtk;
using GLib;
using Pango;

namespace Debins {

    [GtkTemplate (ui="/ui/MainWindow.ui")]
    public class MainWindow : ApplicationWindow {

        [GtkChild]
        AboutDialog dialog_about;

        PackageManager packageManager;
        
        //  UI File elements:
        [GtkChild]
        HeaderBar headerbar;

        [GtkChild]
        Stack stack_windows;

        [GtkChild]
        Button btn_install;
        [GtkChild]
        Button btn_remove;
        [GtkChild]
        Stack stack_buttons;
        [GtkChild]
        Image img_installedIcon;
        [GtkChild]
        Label lbl_packageName;
        [GtkChild]
        Label lbl_subInfo;
        
        [GtkChild]
        Image img_install;
        [GtkChild]
        Image img_reinstall;
        [GtkChild]
        Image img_upgrade;
        [GtkChild]
        Image img_downgrade;

        [GtkChild]
        Label lbl_package_info;

        public MainWindow(App app, PackageManager? packageManager) {
            Object(application: app); // Calling the base class constructor

            if (packageManager != null){
                this.packageManager = packageManager;
                addGUIComponents();
                addGUIEvents();
                refreshGUI();

                stack_windows.set_visible_child_name("main");
            }
            else
                stack_windows.set_visible_child_name("browse");
            
        }

        // Open File Window:
        [GtkCallback]
        private void btn_browse_clicked(Button btn) {
            var fileChooser = new FileChooserNative ("Dosya Aç", this, FileChooserAction.OPEN, null, null);
            var debFilter = new FileFilter();
            debFilter.add_pattern("*.kur");
            fileChooser.add_filter(debFilter);

            if (fileChooser.run () == ResponseType.ACCEPT) {
                File file = File.new_for_path(fileChooser.get_filename());
                this.packageManager = new PackageManager(file);
                addGUIComponents();
                addGUIEvents();
                refreshGUI();

                stack_windows.set_visible_child_name("main");
            }
            fileChooser.destroy ();
        }

        // Main Window:
        [GtkCallback]
        private void btn_install_clicked(Button btn) {
            stack_buttons.set_visible_child_name("loading");

            packageManager.install();
        }
        
        [GtkCallback]
        private void btn_remove_clicked(Button btn) {
            stack_buttons.set_visible_child_name("loading");

            packageManager.uninstall();
        }

        [GtkCallback]
        private void btn_info_clicked(Button btn) {
            stack_windows.set_visible_child_name("info");
        }
        [GtkCallback]
        private void btn_info_back_clicked(Button btn) {
            stack_windows.set_visible_child_name("main");
        }
        [GtkCallback]
        private void btn_info_app_clicked(Button btn) {
            dialog_about.run();
            dialog_about.hide();
        }

        private void addGUIEvents() {
            packageManager.onOutput.connect((output) => {
                print(output);
            });
            packageManager.onFinished.connect((status) => {
                packageManager.refreshPackageInfo();
                stack_buttons.set_visible_child_name("buttons");
                this.refreshGUI();
            });
        }

        private void addGUIComponents() {
            headerbar.subtitle = packageManager.fileName;

            lbl_packageName.set_label(packageManager.packageName);

            string packageSize = packageManager.packageSize > 1000000000 ? "" + (packageManager.packageSize / 1000000000).to_string() + " GB"
                                : packageManager.packageSize > 1000000 ? "" + (packageManager.packageSize / 1000000).to_string() + " MB"
                                : packageManager.packageSize > 1000 ? "" + (packageManager.packageSize / 1000).to_string() + " KB"
                                : "" + packageManager.packageSize.to_string() + " B";
            lbl_subInfo.set_label(packageSize + " | " + packageManager.packageVersion);
        }

        public void refreshInfo() {
            lbl_package_info.set_text(packageManager.packageInfo);
        }

        public void refreshGUI() {
            img_installedIcon.visible = packageManager.isExists;
            lbl_packageName.halign = (packageManager.isExists ? Align.END: Align.CENTER);

            if (packageManager.isUpgradeable){
                btn_install.image = img_upgrade;
                btn_install.label = "Yükselt\n" + packageManager.packageExistingVersion.to_string() + " -> " + packageManager.packageVersion;
                btn_install.tooltip_text = btn_install.label;

                // These code is just making the button's label justified center:
                ((btn_install.get_child() as Gtk.Alignment).get_child() as Box).foreach((item) => {
                    if(item is Label) {
                        Label lbl = item as Label;
                        lbl.ellipsize = EllipsizeMode.END;
                        lbl.justify = Justification.CENTER;
                    }
                });
            } else if (packageManager.isDowngradeable){
                btn_install.image = img_downgrade;
                btn_install.label = "Sürüm Düşür\n" + packageManager.packageExistingVersion.to_string() + " -> " + packageManager.packageVersion;
                btn_install.tooltip_text = btn_install.label;

                // These code is just making the button's label justified center:
                ((btn_install.get_child() as Gtk.Alignment).get_child() as Box).foreach((item) => {
                    if(item is Label) {
                        Label lbl = item as Label;
                        lbl.ellipsize = EllipsizeMode.END;
                        lbl.justify = Justification.CENTER;
                    }
                });
            } else if (packageManager.isExists){
                btn_install.image = img_reinstall;
                btn_install.label = "Tekrar Kur";
            } else {
                btn_install.image = img_install;
                btn_install.label = "Kur";
            }

            btn_remove.visible = packageManager.isExists;

            refreshInfo();
        }
    }
}
